﻿module FsMgDriver
open System.IO
open System.Net.Sockets
open FsMgProtocol
open FsBson

let openDb() = 
    let tcp = new TcpClient()
    tcp.Connect(System.Net.IPAddress.Loopback,27017)
    tcp

let closeDb (conn:TcpClient) = conn.Close()

let defQ = {Id=1;Collection=""; Flags=QueryFlags.None; Skip=0; Take=1; Query=bson[]; Fields=None}

let query queryRec (conn:TcpClient) =
    let cmd = queryRec |> Query
    let str = conn.GetStream()
    FsMgProtocol.serialize cmd str
    let reply = FsMgProtocol.deserializeReply(str)
    reply
    
let findOne collection bson (conn:TcpClient) : Bson option =
    let qrec = {defQ with Id=nextCmdId(); Collection=collection; Take=1; Query=bson; Fields=None} 
    let reply = query qrec conn
    if reply.Count > 0 then Some (reply.Results |> Seq.nth 0)
    else None

let nonQuery cmd (conn:TcpClient) = 
    let str = conn.GetStream()
    FsMgProtocol.serialize cmd str

let insert collection bsons (conn:TcpClient) =
    let cmd = {Id=nextCmdId(); Collection=collection; Flags=InsertFlags.ContinueOnError; Documents=bsons} |> Insert
    nonQuery cmd conn

let update collection bSelector bUpdate flags conn =
    let cmd = {OpUpdateMsg.Id=nextCmdId(); Collection=collection; Flags=flags; Selector=bSelector; Update=bUpdate} |> Update
    nonQuery cmd conn

let delete collection selector flags conn =
    let cmd = {OpDeleteMsg.Id=nextCmdId(); Collection=collection; Flags=flags; Selector=selector} |> Delete
    nonQuery cmd conn

let findOneC  c b =
    let conn = openDb()
    try
        findOne c b conn
    finally
        conn.Close()

let queryC c = 
    let conn = openDb()
    try
    query c conn
    finally
    conn.Close()

let insertC c bson = 
    let conn = openDb()
    try
    insert c bson conn
    finally
    conn.Close()

let updateC collection bSelector bUpdate flags = 
    let conn = openDb()
    try
    update collection bSelector bUpdate flags conn
    finally
    conn.Close()

let deleteC collection selector flags =
    let conn = openDb()
    try
        delete collection selector flags conn
    finally
        conn.Close()
   